#!/usr/bin/perl
# add-server.pl
# Copyright (C) 2006, 2007  Stephane Alnet
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 

package CCNCore::spool::add_server;
use strict; use warnings;

use CCNCore::Provisioning::Local;
use CCNCore::Provision::Unspool;

our $D;

sub run
{
    my $ticket   = pop;
    my $callback = pop;

    my ($ip,$login,$password) = @_;
    
    use CCN::Text;
    $login    = CCN::Text::hex_to_text($login);
    $password = CCN::Text::hex_to_text($password);
    
    my $p = new CCNCore::Provisioning::Local;
    my $s = new CCNCore::Provision::Unspool($p,$callback,$ticket);

    # Can only do this if we are a manager node
    return $D->log('only a manager server can run add_server')
        unless $p->is_manager;

    # Send an HTTPS query to the specified server
    use LWP::UserAgent;
    my $ua = new LWP::UserAgent;

    # Send manager's (=our local) pubkey to the new server
    # (so that it gets added to the authorized_keys list). (See get-info.pl)
    my $ssh_pubkey = CCN::Text::text_to_hex(content_of("$ENV{HOME}/.ssh/id_rsa.pub"));
    
    my $req = new HTTP::Request (POST => "https://$ip/cgi/get-info.pl");
    $req->content_type('application/x-www-form-urlencoded');
    $req->content(join('&',".group=0",".login_name=$login",".password=$password",".manager_pubkey=$ssh_pubkey"));

    # Pass request to the user agent and get a response back
    my $res = $ua->request($req);

    # Check the outcome of the response
    if ($res->is_success)
    {
        my $response = $res->content;

        # Extract the public ssh key and store it locally (=on the manager)
        return $D->log("could not find pubkey in $response")
            unless $response =~ /^pubkey=([\dA-F]+)/i;

        use CCNCore::Home;
        mkdir CCNCore::Home::config."/system/$ip";
        my $failure = print_to(CCNCore::Home::config."/system/$ip/id_rsa.pub", CCN::Text::hex_to_text($1));
        return $D->log("Could not save public key: $failure")
            if $failure;

        # Notify sender if successful.
        use CCN::Text;
        defined $s->reply(CCN::Text::text_to_hex($response))
            or return $D->log("Could not spool reply back");
        $D->log('success');
    }
    else
    {
        $D->log('failure: '.$res->status_line);
    }
}

1;